package pdfsetter.core;

import java.io.File;
import java.io.IOException;
import java.util.ArrayList;
import java.util.LinkedList;
import java.util.List;

import org.apache.pdfbox.pdmodel.PDDocument;

import pdfsetter.core.pages.PageInfo;
import pdfsetter.core.pages.PageRectangle;
import pdfsetter.core.pages.PageType;
import pdfsetter.core.schema.DocumentSchema;
import pdfsetter.core.schema.FillingSchema;
import pdfsetter.core.schema.PageBuildSchema;
import pdfsetter.core.schema.PageInsertSchema;
import pdfsetter.core.schema.PageSelection;
import pdfsetter.core.schema.SimpleDocumentSchema;
import pdfsetter.core.schema.SinglePageSchema;
import pdfsetter.core.schema.advanced.AttachedFilePageSelector;
import pdfsetter.core.schema.advanced.ConsecutiveFileListProcessPattern;
import pdfsetter.core.schema.advanced.FillingSchemaPattern;
import pdfsetter.core.schema.advanced.RepetitiveFileListProcessPattern;
import pdfsetter.core.schema.selectors.LeapingPageSelector;
import pdfsetter.impl.pdfbox.compiler.PdfBoxDocumentCompiler;

public class AdvancedSettingExample {

    public static void docTest(DocumentSchema doc) {
        System.out.println("\n-------- OUTPUT for some DocumentSchema ---------");
        for (PageBuildSchema pbs : doc.getPageBuildSchemas()) {
            PageInfo pinfo = pbs.getPageInfo();
            System.out.println("Page info: " + pinfo.getHeight() + "(h), " + pinfo.getWidth() + "(w)");
            for (PageInsertSchema pis : pbs.getPageInsertSchemas()) {
                PageRectangle prec = pis.getDestinationPageRectangle();
                System.out.println("Rectangle: " + prec.getHeight() + "(h), " + prec.getWidth() + "(w), " + prec.getHorizontalShift() + "(hor shift), "
                        + prec.getVerticalShift() + "(ver shift), " + prec.getRotation() + "(r)");
                PageSelection psel = pis.getPageSelection();
                System.out.println("Selection: " + psel.getFileNumber() + "(f num), " + psel.getPageNumber() + "(p num)");
            }
            System.out.println("-----------");
        }
        System.out.println("-------------------------------------------------\n");
    }

    public static void main(String args[]) {
        System.out.println("Hello! This is simple advanced schemas setting example.");

        PageInfo a4page = new PageInfo(PageType.A4).rotate();
        ArrayList<PageRectangle> locations = new ArrayList<PageRectangle>();
        locations.add(new PageRectangle(0, 0, a4page.getWidth() / 2, a4page.getHeight(), 0));
        locations.add(new PageRectangle(a4page.getWidth() / 2, 0, a4page.getWidth() / 2, a4page.getHeight(), 0));
        SinglePageSchema pageSchema = new SinglePageSchema("2xA5 on A4", a4page, locations);

        // ------------ Input Files --------------
        List<File> files = new LinkedList<File>();
        files.add(new File("src/test/resources/test-pdf-1.pdf"));
        files.add(new File("src/test/resources/test-pdf-2.pdf"));

        // Load source documents and retrieve document sizes
        int[] fileSizes = new int[files.size()];
        int i = 0;
        for (File file : files) {
            try {
                PDDocument pdd = PDDocument.loadNonSeq(file, null);
                fileSizes[i] = pdd.getNumberOfPages();
                System.out.println("File info: " + fileSizes[i] + "(pages)");
                pdd.close();
            } catch (IOException e) {
                e.printStackTrace();
            }
            i++;
        }
        // ------------ Use patterns and create and test FillingSchemas -------------
        ArrayList<AttachedFilePageSelector> asList = new ArrayList<AttachedFilePageSelector>();
        asList.add(new AttachedFilePageSelector(new LeapingPageSelector(2), 0)); // take every second from 0-file
        FillingSchemaPattern con1 = new ConsecutiveFileListProcessPattern(asList);
        asList.add(new AttachedFilePageSelector(new LeapingPageSelector(4), 1)); // take every forth from 1-file
        FillingSchemaPattern con2 = new ConsecutiveFileListProcessPattern(asList); //
        FillingSchemaPattern rep2 = new RepetitiveFileListProcessPattern(asList);

        setCompileSave(pageSchema, con1.produceFillingSchema(fileSizes), files, "out-test/out-con1.pdf"); // every second, only from 0-file
        setCompileSave(pageSchema, con2.produceFillingSchema(fileSizes), files, "out-test/out-con2.pdf"); // every second + every forth | consecutive
        setCompileSave(pageSchema, rep2.produceFillingSchema(fileSizes), files, "out-test/out-rep2.pdf"); // every second + every forth | repetitive
    }

    public static void setCompileSave(SinglePageSchema pageSchema, FillingSchema fillSchema, List<File> files, String outPath) {
        DocumentSchema doc = new SimpleDocumentSchema(pageSchema, fillSchema);
        docTest(doc);
        File out = new File(outPath);
        new PdfBoxDocumentCompiler().compile(doc, files, out);
    }
}
